/*
 * BSM6.0
 *
 * Copyright 2012-2013 (C) SINODATA CO., LTD. All Rights Reserved.
 */
package com.sinodata.bsm.center.web.action.resource;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;

import com.sinodata.bsm.center.bean.ResBean;
import com.sinodata.bsm.center.service.resource.ResHealthService;
import com.sinodata.bsm.center.service.resource.ResService;
import com.sinodata.bsm.center.service.resource.ResTypeService;
import com.sinodata.bsm.center.util.web.Struts2Utils;
import com.sinodata.bsm.center.web.action.BaseAction;
import com.sinodata.bsm.common.constants.ResConstants;
import com.sinodata.bsm.common.exception.InvalidArgumentException;
import com.sinodata.bsm.common.utils.DateUtil;
import com.sinodata.bsm.common.vo.HealthCalcRule;
import com.sinodata.bsm.common.vo.HealthStatusStatHour;
import com.sinodata.bsm.common.vo.HealthTransRule;
import com.sinodata.bsm.common.vo.Res;
import com.sinodata.bsm.common.vo.ResType;

/**
 * <p>
 * Description: 
 * </p>
 *
 * @author fanshengchao
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-6-26 上午10:49:06          fanshengchao        1.0         To create
 * </p>
 *
 * @since 
 * @see     
 */
public class ResHealthyAction extends BaseAction<HealthCalcRule> {
    private HealthCalcRule entity;
    private Long id;

    @Autowired
    private ResService resService;
    @Autowired
    private ResTypeService resTypeService;
    @Autowired
    private ResHealthService resHealthService;

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#delete()
     */
    @Override
    public String delete() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#input()
     */
    @Override
    public String input() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * 显示子资源的健康度结果集
     */
    @Override
    public String list() throws Exception {
        Long resId = Long.parseLong(Struts2Utils.getParameter("resId"));
        ResBean[] beans = ResBean.get(resId).children();

        Integer sumWeight = 0;
        //计算权重比例
        for (int i = 0; i < beans.length; i++) {
            Res res = beans[i].res();
            //获取修改的权重
            Integer weight = null;
            List<HealthTransRule> transRules = resHealthService.findChildHealthTransRule(resId);
            for (int r = 0; transRules != null && r < transRules.size(); r++) {
                HealthTransRule rule = transRules.get(r);
                if (rule.getChildResId().longValue() == res.getId().longValue()) {
                    if (rule.getIsTrans().intValue() == ResConstants.STATUS_TRANSFER) {
                        weight = rule.getWeight();
                    } else if (rule.getIsTrans().intValue() == ResConstants.NOT_TRANSFER) {
                        weight = 0;
                    }
                    break;
                }
            }

            if (weight == null) {
                sumWeight = (sumWeight.intValue() + 5);
            } else {
                sumWeight = (sumWeight.intValue() + weight.intValue());
            }
        }
        JSONArray childRes = new JSONArray();
        JSONObject json = new JSONObject();
        for (int i = 0; i < beans.length; i++) {
            Res res = beans[i].res();
            JSONObject object = new JSONObject();
            object.element("checkbox", "<input type='checkbox'  name='res_check'   id='res_check' value='" + res.getId() + "'>");
            object.element("name", res.getName());
            ResType resType = resTypeService.get(res.getResTypeId());
            object.element("resTypeName", resType.getName());

            List<HealthTransRule> transRules = resHealthService.findChildHealthTransRule(resId);
            Integer isTran = 1;
            Integer weight = 5;
            for (int r = 0; transRules != null && r < transRules.size(); r++) {
                HealthTransRule rule = transRules.get(r);
                if (rule.getChildResId().longValue() == res.getId().longValue()) {
                    isTran = rule.getIsTrans();
                    weight = rule.getWeight() == null ? 0 : rule.getWeight();
                    break;
                }
            }
            object.element("isTrans", isTran == ResConstants.STATUS_TRANSFER ? "传递" : "不传递");
            object.element("weight", isTran == 0 ? "" : weight);
            //获取修改的权重
            DecimalFormat df = new DecimalFormat("##0%");
            //相除分母不能为0(无意义) 
            Double value = weight.doubleValue() / (sumWeight == 0 ? 1 : sumWeight);
            String weightProportion = df.format(value);
            object.element("weightProportion", weightProportion);
            object.element("id", res.getId());
            object.element("weightAndProportion", "");
            childRes.add(object);
        }

        json.element("aaData", childRes);
        json.element("iTotalRecords", 0);
        json.element("iTotalDisplayRecords", 0);
        Struts2Utils.renderText(json.toString());
        return null;
    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#prepareModel()
     */
    @Override
    protected void prepareModel() throws Exception {
        if (id == null) {
            entity = new HealthCalcRule();
        } else {
            entity = resHealthService.findByResId(id);
        }

    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#save()
     */
    @Override
    public String save() throws Exception {
        try {
            resHealthService.saveOrUpdateHealthCalcRule(entity);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String config() {
        Long resId = Long.parseLong(Struts2Utils.getParameter("id"));
        Res res = resService.get(resId);
        HealthCalcRule entity = resHealthService.findByResId(resId);
        HealthCalcRule healthRule = new HealthCalcRule();
        if (res != null) {
            healthRule.setId(res.getId());
            healthRule.setArithmetic(entity == null ? 1 : entity.getArithmetic());
        }

        Struts2Utils.setRequestAttribute("healthRule", healthRule);
        Struts2Utils.setRequestAttribute("res", res);
        return "config";
    }

    /**
     * 子资源健康传递规则设置页面
     * @return
     */
    public String rule() {
        return "rule";
    }

    public String saveHealthTransRule() throws InvalidArgumentException {
        String rules = Struts2Utils.getParameter("rules");
        Long resId = Long.parseLong(Struts2Utils.getParameter("resId"));
        String[] strs = rules.split(",");
        List<HealthTransRule> transRule = new ArrayList<HealthTransRule>();
        for (int i = 0; i < strs.length; i++) {
            String[] ruleValues = strs[i].split("#");
            HealthTransRule rule = new HealthTransRule();
            Long parentResId = Long.parseLong(ruleValues[0]);
            Long childResId = Long.parseLong(ruleValues[1]);
            Integer isTrans = Integer.parseInt(ruleValues[2]);
            if (isTrans.intValue() == ResConstants.STATUS_TRANSFER) {
                Integer weight = Integer.parseInt(ruleValues[3]);
                rule.setWeight(weight);
            }

            rule.setParentResId(parentResId);
            rule.setChildResId(childResId);
            rule.setIsTrans(isTrans);

            transRule.add(rule);
        }
        resHealthService.saveHealthTransRule(resId, transRule);
        return null;
    }

    public String analysis() {
        request.setAttribute("res", resService.get(this.id));
        return "analysis";
    }

    public String history() {
        request.setAttribute("res", resService.get(this.id));
        return "history";
    }

    public String findResHealthData() {
        String choose = request.getParameter("choose");
        String[] dateScope = Struts2Utils.getParameter("dateScope").split("[|]");
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.HOUR_OF_DAY, -1);
        Date endTime = cal.getTime();
        SimpleDateFormat ff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String strEndTime = ff.format(endTime);

        int table = Integer.parseInt(Struts2Utils.getParameter("dimension"));
        if (choose.equals("1")) {//近24小时内
            cal.add(Calendar.DATE, -1);
        } else if (choose.equals("7")) {//近7天内
            cal.add(Calendar.DATE, -7);

        } else if (choose.equals("30")) {//近一个月
            cal.add(Calendar.MONTH, -1);

        } else {
            //自定义
            if (table == 1) {
                strEndTime = ff.format(DateUtil.parseDate(dateScope[1].replace(" 时", "") + ":00:00", "yyyy-MM-dd hh:mm:ss"));
            } else {
                strEndTime = ff.format(DateUtil.parseDate(dateScope[1] + " 00:00:00", "yyyy-MM-dd hh:mm:ss"));
            }
        }
        Date startDate = cal.getTime();
        if (table == 1 && choose.equals("0")) {
            startDate = DateUtil.parseDate(dateScope[0].replace(" 时", "") + ":00:00", "yyyy-MM-dd hh:mm:ss");
        } else if (table == 2 && choose.equals("0")) {
            startDate = DateUtil.parseDate(dateScope[0] + " 00:00:00", "yyyy-MM-dd hh:mm:ss");
        }

        List<HealthStatusStatHour> list = resHealthService.queryResHealthHis(this.id, ff.format(startDate), strEndTime, table);

        JSONArray array = new JSONArray();

        for (int i = 0; i < list.size(); i++) {
            HealthStatusStatHour val = list.get(i);
            JSONObject json = new JSONObject();
            json.element("degree", val.getDegree());
            Date d = val.getTime();
            cal = Calendar.getInstance();
            cal.setTime(d);

            if (table == 1) {
                //时汇聚
                int hour = cal.get(Calendar.HOUR_OF_DAY);
                json.element("time", hour + "时");
            } else {
                //日
                ff.applyPattern("MM/dd");
                json.element("time", ff.format(d));
            }
            json.element("normal", Math.round(val.getNormalTime() / 60));
            json.element("minor", Math.round(val.getMinorTime() / 60));
            json.element("warn", Math.round(val.getWarnTime() / 60));
            json.element("major", Math.round(val.getMajorTime() / 60));
            json.element("critical", Math.round(val.getCriticalTime() / 60));
            array.add(json);
        }
        Struts2Utils.renderText(array.toString());
        return null;
    }

    @SuppressWarnings("unchecked")
    public String findHealthyHistory() {
        String dimension = Struts2Utils.getParameter("dimension");
        String[] dateScope = Struts2Utils.getParameter("dateScope").split("[|]");
        String timeScope = Struts2Utils.getParameter("timeScope");
        Calendar cal = Calendar.getInstance();
        Date endTime = cal.getTime();
        SimpleDateFormat ff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String strEndTime = ff.format(endTime);
        if (timeScope.equals("1")) {//近24小时内
            cal.add(Calendar.DATE, -1);
        } else if (timeScope.equals("7")) {//近7天内
            cal.add(Calendar.DATE, -7);

        } else if (timeScope.equals("30")) {//近一个月
            cal.add(Calendar.MONTH, -1);

        } else {
            //自定义
            if (dimension.equals("1")) {
                strEndTime = ff.format(DateUtil.parseDate(dateScope[1].replace(" 时", "") + ":00:00", "yyyy-MM-dd hh:mm:ss"));
            } else {
                strEndTime = ff.format(DateUtil.parseDate(dateScope[1] + " 00:00:00", "yyyy-MM-dd hh:mm:ss"));
            }

        }
        Date startDate = cal.getTime();
        if (dimension.equals("1") && timeScope.equals("0")) {
            startDate = DateUtil.parseDate(dateScope[0].replace(" 时", "") + ":00:00", "yyyy-MM-dd hh:mm:ss");
        } else if (dimension.equals("2") && timeScope.equals("0")) {
            startDate = DateUtil.parseDate(dateScope[0] + " 00:00:00", "yyyy-MM-dd hh:mm:ss");
        }

        if (dimension.equals("1")) {
            startDate.setTime(startDate.getTime() - 3600000);
        } else {
            startDate.setTime(startDate.getTime() - 86400000);
        }

        List<HealthStatusStatHour> list = resHealthService.queryResHealthHis(this.id, ff.format(startDate), strEndTime, Integer.parseInt(dimension));

        Collections.sort(list, new Comparator<HealthStatusStatHour>() {
            @Override
            public int compare(HealthStatusStatHour o1, HealthStatusStatHour o2) {
                // TODO Auto-generated method stub
                return (int) (o2.getTime().getTime() - o1.getTime().getTime());
            }
        });

        JSONObject json = new JSONObject();
        JSONArray array = new JSONArray();
        for (int i = 0; list != null && i < list.size(); i++) {
            HealthStatusStatHour stathour = list.get(i);
            JSONObject object = new JSONObject();
            object.element("time", DateUtil.format(stathour.getTime(), dimension.equals("1") ? "yyyy-MM-dd HH" : "yyyy-MM-dd"));
            object.element("degree", stathour.getDegree());
            Long countTime = stathour.getNormalTime() + stathour.getMinorTime() + stathour.getWarnTime() + stathour.getMajorTime() + stathour.getCriticalTime();
            DecimalFormat df = new DecimalFormat("##0%");
            object.element("normalTime", df.format(Double.valueOf(stathour.getNormalTime()) / Double.valueOf(countTime)));
            object.element("minorTime", df.format(Double.valueOf(stathour.getMinorTime()) / Double.valueOf(countTime)));
            object.element("warnTime", df.format(Double.valueOf(stathour.getWarnTime()) / Double.valueOf(countTime)));
            object.element("majorTime", df.format(Double.valueOf(stathour.getMajorTime()) / Double.valueOf(countTime)));
            object.element("criticalTime", df.format(Double.valueOf(stathour.getCriticalTime()) / Double.valueOf(countTime)));

            array.add(object);
        }
        json.element("aaData", array);
        json.element("iTotalRecords", array.size());
        json.element("iTotalDisplayRecords", array.size());
        Struts2Utils.renderText(json.toString());
        return null;
    }

    /* (non-Javadoc)
     * @see com.opensymphony.xwork2.ModelDriven#getModel()
     */
    @Override
    public HealthCalcRule getModel() {
        // TODO Auto-generated method stub
        return entity;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}
